﻿//*********************************************************
//
// Copyright (c) Microsoft. All rights reserved.
//
//*********************************************************

#pragma once
#include "pch.h"
#include "DirectXPanelBase.h"
#include "StepTimer.h"
#include "ShaderStructures.h"

#include "Color.h"
#include "Vector2.h"
#include "Vector4.h"
#include "Texture.h"

#include "..\..\DirectXTK\Inc\Audio.h"
#include "..\..\DirectXTK\Inc\CommonStates.h"
#include "..\..\DirectXTK\Inc\Effects.h"
#include "..\..\DirectXTK\Inc\GeometricPrimitive.h"
#include "..\..\DirectXTK\Inc\Model.h"
#include "..\..\DirectXTK\Inc\PrimitiveBatch.h"
#include "..\..\DirectXTK\Inc\SpriteBatch.h"
#include "..\..\DirectXTK\Inc\SpriteFont.h"
#include "..\..\DirectXTK\Inc\VertexTypes.h"

#include <mutex>
#include <map>

namespace SharpDepend_UWP_DirectXInterop
{
    // Hosts a DirectX rendering surface that draws a spinning 3D cube using Direct3D.

    [Windows::Foundation::Metadata::WebHostHidden]
    public ref class D3DPanel sealed : public SharpDepend_UWP_DirectXInterop::DirectXPanelBase
    {
		ID3D11ShaderResourceView* CreateSquareTexture(int width, int height, int* data);

		// New stuff.
		std::unique_ptr<DirectX::CommonStates>                                  m_states;
		std::unique_ptr<DirectX::SpriteBatch>                                   m_sprites;
		std::unique_ptr<DirectX::PrimitiveBatch<DirectX::VertexPositionColorTexture>>  m_batch;
		std::unique_ptr<DirectX::BasicEffect>                                   m_batchEffect;
		Microsoft::WRL::ComPtr<ID3D11InputLayout>                               m_batchInputLayout;

		std::map<int, ID3D11ShaderResourceView*>								m_textures;
		Microsoft::WRL::ComPtr<ID3D11ShaderResourceView>						m_nullTexture;

		DirectX::XMFLOAT4X4 m_world;
		DirectX::XMFLOAT4X4 m_view;
		DirectX::XMFLOAT4X4 m_projection;

		ID3D11BlendState* NonPremultiplied;

		std::mutex mMutes;

    public:
        D3DPanel();

	private protected:
		void OnBeginDraw() override;
		void OnDrawRectangle(
			float x1, float y1, float x2, float y2,
			float r, float g, float b, float a,
			int textureId,
			float td_x1, float td_y1, float td_x2, float td_y2,
			int textureWidth, int textureHeight) override;
		void OnDrawLine(
			float x1, float y1, float x2, float y2,
			float r, float g, float b, float a) override;
		void OnDrawCircle(
			float x, float y, float radius,
			float r, float g, float b, float a) override;
		void OnDrawTriangles(Vector2Double* vertices, int verticesLength, unsigned short* indices, int indicesLength, ColorUInt* colors, int colorLength) override;
		void OnEndDraw() override;

		void OnRegisterTexture(int id, int* data, int dataLength, int width, int height) override;
		void OnUnregisterTexture(int id) override;
		void OnUpdateTexture(int id, int* data, int width, int height) override;

    private protected:

		virtual void Render() override { };
        virtual void CreateDeviceResources() override;
        virtual void CreateSizeDependentResources() override;

        Microsoft::WRL::ComPtr<IDXGIOutput>                 m_dxgiOutput;

        Microsoft::WRL::ComPtr<ID3D11RenderTargetView>      m_renderTargetView;
        Microsoft::WRL::ComPtr<ID3D11DepthStencilView>      m_depthStencilView;
        Microsoft::WRL::ComPtr<ID3D11VertexShader>          m_vertexShader;
        Microsoft::WRL::ComPtr<ID3D11PixelShader>           m_pixelShader;
        Microsoft::WRL::ComPtr<ID3D11InputLayout>           m_inputLayout;
        Microsoft::WRL::ComPtr<ID3D11Buffer>                m_vertexBuffer;
        Microsoft::WRL::ComPtr<ID3D11Buffer>                m_indexBuffer;
        Microsoft::WRL::ComPtr<ID3D11Buffer>                m_constantBuffer;

        DX::ModelViewProjectionConstantBuffer               m_constantBufferData;

        uint32                                              m_indexCount;

        float	                                            m_degreesPerSecond;

    private:
        ~D3DPanel();

		struct Batch
		{
			enum class ShapeType : unsigned char
			{
				Rectangle,
				Line,
				Circle,
				Triangles
			};

			Vector4 rectangle;
			Vector4 textureCoords;
			Color color;
			int textureId;

			int textureWidth;
			int textureHeight;

			ShapeType Type;

			// For Triangles.
			Vector2Double* vertices;
			int verticesLength;
			uint16_t* indices;
			int indicesLength;
			ColorUInt* colors;
			int colorLength;
		};

		std::vector<Batch> mBatch;
    };
}